package com.ihd.ihardware.common.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import com.ihd.ihardware.R;

import java.util.List;


public class DashBoardView extends View {

    private static final int TRAN_COLOR = Color.parseColor("#00000000");
    private static final int GREEN_COLOR = Color.parseColor("#80E15A");
    private int defaultSize;
    private PaintFlagsDrawFilter mPaintFlagsDrawFilter;
    private Paint mOuterGradientPaint;
    private int width;
    private float radius;
    private int[] mColors = {Color.parseColor("#FFCFFFF6"), Color.parseColor("#FF72FFDA"), Color.parseColor("#FFFFC365")};
    private int height;
    private List<String> valueList;
    private Paint mMiddleProgressPaint;
    private Paint mPointerBitmapPaint;
    private Bitmap mBitmap;
    private int mBitmapHeight;
    private int mBitmapWidth;
    private RectF mOuterRectF;
    private float oval4;
    private float mStartAngle = 0f;
    private RectF mMiddleProgressRectF;
    private float mEndAngle = 180f;
    private int mAnimatorValue;
    private float mCurrentAngle;
    private float mTotalAngle;
    private int mCurrentValue;

    public DashBoardView(Context context) {
        super(context);
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        //设置默认宽高值
        defaultSize = dp2px(260);

        //设置图片线条的抗锯齿
        mPaintFlagsDrawFilter = new PaintFlagsDrawFilter
                (0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);

        //最外层圆环渐变画笔设置
        mOuterGradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置圆环渐变色渲染
        mOuterGradientPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        Shader mShader = new SweepGradient(width / 2, radius + dp2px(5), mColors, null);
        mOuterGradientPaint.setShader(mShader);
        mOuterGradientPaint.setStrokeCap(Paint.Cap.ROUND);
        mOuterGradientPaint.setStyle(Paint.Style.STROKE);
        mOuterGradientPaint.setStrokeWidth(27);

        //中间圆环进度画笔设置
        mMiddleProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mMiddleProgressPaint.setColor(TRAN_COLOR);
        mMiddleProgressPaint.setStrokeCap(Paint.Cap.ROUND);
        mMiddleProgressPaint.setStrokeWidth(5);
        mMiddleProgressPaint.setStyle(Paint.Style.STROKE);

        //指针图片画笔
        mPointerBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPointerBitmapPaint.setColor(GREEN_COLOR);

        //获取指针图片及宽高
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.index_point);
        mBitmapHeight = mBitmap.getHeight();
        mBitmapWidth = mBitmap.getWidth();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(remeasure(widthMeasureSpec, defaultSize),
                remeasure(heightMeasureSpec, defaultSize));
    }

    /**
     * 根据传入的值进行重新测量
     */
    private int remeasure(int measureSpec, int defaultSize) {

        int result;
        int specSize = MeasureSpec.getSize(measureSpec);
        switch (MeasureSpec.getMode(measureSpec)) {
            case MeasureSpec.UNSPECIFIED:
                //未指定
                result = defaultSize;
                break;
            case MeasureSpec.AT_MOST:
                //设置warp_content时设置默认值
                result = Math.min(specSize, defaultSize);
                break;
            case MeasureSpec.EXACTLY:
                //设置math_parent 和设置了固定宽高值
                result = specSize;
                break;
            default:
                result = defaultSize;
        }
        return result;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        //确定View宽高
        width = w;
        height = h;

        //圆环半径
        radius = width / 2 - dp2px(7);

        //外层圆环
        float oval1 = radius - mOuterGradientPaint.getStrokeWidth() * 0.5f;
        mOuterRectF = new RectF(-oval1, -oval1, oval1, oval1);

        //中间进度圆环
        oval4 = radius * 13 / 16;
        mMiddleProgressRectF = new RectF(-oval4 + dp2px(10), -oval4 + dp2px(10), oval4 - dp2px(10), oval4 - dp2px(10));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //设置画布绘图无锯齿
        canvas.setDrawFilter(mPaintFlagsDrawFilter);
        //绘制圆弧
        drawArc(canvas);
        //绘制当前bitmap指针指示进度
        drawBitmapProgress(canvas);
    }

    /**
     * 分别绘制外层 中间 内层圆环
     */
    private void drawArc(Canvas canvas) {

        canvas.save();
        canvas.translate(width / 2, height - dp2px(15));
        //画布旋转140°
//        canvas.rotate(100);
        //最外层的渐变圆环
        canvas.drawArc(mOuterRectF, -mStartAngle, -mEndAngle, false, mOuterGradientPaint);
        canvas.restore();
    }

    /**
     * 绘制当前进度和指示图片
     */
    private void drawBitmapProgress(Canvas canvas) {
        //如果当前角度为0，则不绘制指示图片
        if (mCurrentAngle == 0f) {
            return;
        }
        canvas.save();
        canvas.translate(radius + dp2px(7), radius + dp2px(5));
        canvas.rotate(180);
        //绘制对应的圆弧
        canvas.drawArc(mMiddleProgressRectF, -mStartAngle, mCurrentAngle, false, mMiddleProgressPaint);
        canvas.rotate(180 + mCurrentAngle);
        //利用矩阵平移使图片指针方向始终指向刻度
        Matrix matrix = new Matrix();
        matrix.preTranslate(-oval4 - mBitmapWidth * 3 / 8 + 10, -mBitmapHeight / 2);
        canvas.drawBitmap(mBitmap, matrix, mPointerBitmapPaint);
        canvas.restore();
    }

    /**
     * 当前数据对应弧度旋转及当前数据自增动画
     */
    public void startRotateAnim() {

        ValueAnimator mAngleAnim = ValueAnimator.ofFloat(mCurrentAngle, mTotalAngle);
        mAngleAnim.setInterpolator(new AccelerateDecelerateInterpolator());
        mAngleAnim.setDuration(2500);
        mAngleAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                mCurrentAngle = (float) valueAnimator.getAnimatedValue();
                postInvalidate();
            }
        });
        mAngleAnim.start();

        ValueAnimator mNumAnim = ValueAnimator.ofInt(mAnimatorValue, mCurrentValue);
        mNumAnim.setDuration(2500);
        mNumAnim.setInterpolator(new LinearInterpolator());
        mNumAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {

                mAnimatorValue = (int) valueAnimator.getAnimatedValue();
                postInvalidate();
            }
        });
        mNumAnim.start();
    }

    /**
     * 设置数据
     */
    public void setValues(int values, List<String> valueList) {
        this.valueList = valueList;
        if (values <= 0) {
            mCurrentValue = values;
            mTotalAngle = 0f;
        } else if (values <= 14000) {
            mCurrentValue = values;
            mTotalAngle = values / 14000f * 60 - 2;
        } else if (values > 14000 && values <= 17000) {
            mCurrentValue = values;
            mTotalAngle = values / 17000f * 120 - 2;
        } else if (values > 17000 && values <= 21000) {
            mCurrentValue = values;
            mTotalAngle = values / 21000f * 180 - 2;
        } else {
            mCurrentValue = values;
            float ratio = values / 21000f;
            if (ratio < 20) {
                mTotalAngle = ratio + 180;
            } else {
                mTotalAngle = (float) (ratio * 0.2 + 200);
            }
        }

        startRotateAnim();
    }

    private int dp2px(float dp) {
        DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
        return (int) (dp * metrics.density);
    }
}
